package ce.com.cenewbluesdk.uitl;

import java.io.ByteArrayOutputStream;

/**
 * 模仿{@link ByteArrayOutputStream}写的...
 *
 */
public class ByteBuilder {
    private byte[] buf;
    private int count;

    public ByteBuilder(int size) {
        buf = new byte[size];
    }

    public ByteBuilder() {
        this(16);
    }

    public ByteBuilder writeBytes(byte[] buffer) {
        return writeBytes(buffer, 0, buffer.length);
    }

    public ByteBuilder writeBytes(byte[] buffer, int offset, int len) {
        if (len > 0) {
            expand(len);
            System.arraycopy(buffer, offset, buf, count, len);
            count += len;
        }
        return this;
    }

    /**
     * @param str           要添加的字符
     * @param maxLength     字符的占据的byte数
     * @param ifLessAddZero 不足补0
     * @return
     */
    public ByteBuilder writeString(String str, int maxLength, boolean ifLessAddZero) {
//        str = str.replaceAll("[^\\u0000-\\uffff]", "?");// 过滤BMP以外的字符串
        int count = 0;
        for (int i = 0; i < str.length(); i++) {
            int codePointAt = str.codePointAt(i); // codePointAt(), 有可能只取到一对char的一半
            if (codePointAt >= Character.MIN_SURROGATE && codePointAt <= Character.MAX_SURROGATE) {
                // 只取到一对char中的一个, 不需要处理
            } else {
                byte[] b = new String(new int[]{codePointAt}, 0, 1).getBytes();
                int futureCount = count + b.length;
                if (futureCount <= maxLength) {
                    writeBytes(b);
                    count = futureCount;
                } else {
                    break;// 若超过maxLength的长度, 结束
                }
            }
        }
        if (ifLessAddZero && count < maxLength) {// 若不足maxLength, 则补0
            writeBytes(new byte[maxLength - count]);
        }
        return this;
    }

    /**
     * @param value
     * @param len   len取1, 2, 3, 4时分别相当于写入: 无符号的byte, 无符号的short, 无符号的3个字节, 有符号的int
     */
    public ByteBuilder writeInt(int value, int len) {
        if (len > 4) {
            throw new IllegalArgumentException(String.format("len(%s)要小于等于4", len));
        }
        expand(len);
        for (int i = 0; i < len; i++) {
            buf[count + i] = (byte) (value >>> (8 * i));
        }
        count += len;
        return this;
    }

    public ByteBuilder write(byte b) {
        if (count == buf.length) {
            expand(1);
        }
        buf[count++] = b;
        return this;
    }

    /**
     * buf的大小会扩展两倍以上~~
     * 2*count + 2*i
     * @param i
     */
    private void expand(int i) {
        if (count + i <= buf.length) {
            return;
        }
        byte[] newBuf = new byte[(count + i) * 2];
        System.arraycopy(buf, 0, newBuf, 0, count);
        buf = newBuf;
    }

    public int getSize() {
        return count;
    }

    public void reset() {
        count = 0;
    }

    /**
     * @param length 返回的byte[]的大小
     * @return
     */
    public byte[] toByteArray(int length) {
        if (length < count) {
            throw new IllegalArgumentException(String.format("length(%s)比count(%s)小", length, count));
        }
        byte[] newArray = new byte[length];
        System.arraycopy(buf, 0, newArray, 0, count);
        return newArray;
    }

    public byte[] toByteArray() {
        return toByteArray(count);
    }

    public byte[] build() {
        return toByteArray();
    }
}
